package com.lvbaoins.Harmony.system.controller;

import com.lvbaoins.Harmony.core.fastdfs.*;
import com.lvbaoins.Harmony.core.reqres.response.ResponseData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


/**
 * @ClassName: FastDfsFileController.java
 * @Description: fastdfs分布式文件管理controller
 * @version: v1.0.0
 * @author: liwei
 * @date: 2019年7月10日 上午10:08:55
 */
@Controller
@RequestMapping("/dfsfile")
@Slf4j
public class FastDfsFileController {

    @Autowired
    private FastDFSClientComponent fastDFSClientComponent;

    /**
     * 路径分隔符
     */
    public static final String SEPARATOR = "/";
    /**
     * Point
     */
    public static final String POINT = ".";

    public static Map<String, String> EXT_MAPS = new HashMap<String, String>();
    static  {
        // image
        EXT_MAPS.put("png", "image/png");
        EXT_MAPS.put("gif", "image/gif");
        EXT_MAPS.put("bmp", "image/bmp");
        EXT_MAPS.put("ico", "image/x-ico");
        EXT_MAPS.put("jpeg", "image/jpeg");
        EXT_MAPS.put("jpg", "image/jpeg");
        // 压缩文件
        EXT_MAPS.put("zip", "application/zip");
        EXT_MAPS.put("rar", "application/x-rar");
        // doc
        EXT_MAPS.put("pdf", "application/pdf");
        EXT_MAPS.put("ppt", "application/vnd.ms-powerpoint");
        EXT_MAPS.put("xls", "application/vnd.ms-excel");
        EXT_MAPS.put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        EXT_MAPS.put("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
        EXT_MAPS.put("doc", "application/msword");
        EXT_MAPS.put("doc", "application/wps-office.doc");
        EXT_MAPS.put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        EXT_MAPS.put("txt", "text/plain");
        // 音频
        EXT_MAPS.put("mp4", "video/mp4");
        EXT_MAPS.put("flv", "video/x-flv");
    }

    /**
     * @Title: upload
     * @Description: 上传附件
     * @param: request
     * @param: response
     * @return: JSONObject
     */
    @RequestMapping(value = "upload")
    @ResponseBody
    public ResponseData upload(HttpServletRequest request, HttpServletResponse response) {

        FileResponseData responseData = new FileResponseData();
        try {
            //进行转换
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) (request);
            //获取所有文件名称
            Iterator<String> it = multiRequest.getFileNames();
            //根据文件名称取文件
            MultipartFile file = multiRequest.getFile(it.next());

            String filepath = fastDFSClientComponent.uploadFile(file);

            responseData.setFileName(file.getOriginalFilename());
            responseData.setFilePath(filepath);
            responseData.setFileType(getFilenameSuffix(file.getOriginalFilename()));
        } catch (Exception e) {
            log.error("[上传图片或文件]-错误:{}", e.getMessage());
            return ResponseData.error(e.getMessage());
        }

        return ResponseData.success(responseData);
    }

    /**
     * 获取文件名称的后缀
     *
     * @param filename 文件名 或 文件路径
     * @return 文件后缀
     */
    public static String getFilenameSuffix(String filename) {
        String suffix = null;
        String originalFilename = filename;
        if (StringUtils.isNotBlank(filename)) {
            if (filename.contains(SEPARATOR)) {
                filename = filename.substring(filename.lastIndexOf(SEPARATOR) + 1);
            }
            if (filename.contains(POINT)) {
                suffix = filename.substring(filename.lastIndexOf(POINT) + 1);
            }
        }
        return suffix;
    }


    /**
     * 以附件形式下载文件
     *
     * @param filePath 文件地址
     * @param response
     */
    @RequestMapping("/download/file")
    public void downloadFile(String filePath, HttpServletResponse response) {
        try {
            if(StringUtils.isNoneBlank(filePath)){
                byte[] fileByte = fastDFSClientComponent.download(filePath);

                if (filePath != null) {

                    // 设置响应头
                    // 文件编码 处理文件名中的 '+'、' ' 特殊字符
                    String encoderName = URLEncoder.encode(filePath.substring(filePath.lastIndexOf("/") + 1), "UTF-8").replace("+", "%20").replace("%2B", "+");
                    response.setHeader("Content-Disposition", "attachment;filename=\"" + encoderName + "\"");
                    response.setContentType(this.EXT_MAPS.get(filePath.substring(filePath.lastIndexOf("/") + 1)) + ";charset=UTF-8");
                    response.setHeader("Accept-Ranges", "bytes");
                }
                IOUtils.write(fileByte, response.getOutputStream());
            } else {
                //图片地址为空直接返回   后续处理
                return;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取图片 使用输出流输出字节码，可以使用< img>标签显示图片<br>
     *
     * @param filePath 图片地址
     * @param response
     */
    @RequestMapping("/download/image")
    public void downloadImage(String filePath, HttpServletResponse response) throws Exception {

        OutputStream os = null;
        filePath = toLocal(filePath);
        // 文件名
        String contentType = this.EXT_MAPS.get(filePath.substring(filePath.lastIndexOf(".") + 1));
        InputStream is = null;
        try {
            // 下载
            byte[] fileByte = fastDFSClientComponent.download(filePath);

            if (response != null) {
                os = response.getOutputStream();
                // 设置响应头
                if (StringUtils.isNotBlank(contentType)) {
                    // 文件编码 处理文件名中的 '+'、' ' 特殊字符
                    String encoderName = URLEncoder.encode(filePath.substring(filePath.lastIndexOf("/")), "UTF-8").replace("+", "%20").replace("%2B", "+");
                    //response.setHeader("Content-Disposition", "attachment;filename=\"" + encoderName + "\"");
                    response.setContentType(contentType + ";charset=UTF-8");
                    response.setHeader("Accept-Ranges", "bytes");
                }
            }
            is = new ByteArrayInputStream(fileByte);
            byte[] buffer = new byte[1024 * 5];
            int len = 0;
            while ((len = is.read(buffer)) > 0) {
                os.write(buffer, 0, len);
            }
            os.flush();
        } catch (Exception e) {
            log.error("[查看文件]-错误:{},文件地址:{}", e.getMessage(), filePath);
        } finally {
            // 关闭流
            try {
                if(is != null){
                    is.close();
                }
                if(os != null){
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static String toLocal(String path) {
        if (StringUtils.isNotBlank(path)) {
            path = path.replaceAll("\\\\", SEPARATOR);

            if (path.contains(POINT)) {
                String pre = path.substring(0, path.lastIndexOf(POINT) + 1);
                String suffix = path.substring(path.lastIndexOf(POINT) + 1).toLowerCase();
                path = pre + suffix;
            }
        }
        return path;
    }


}
